<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

    class Generator{

        private $jpeg_quality = 100;
        private $dirImages = "";

        public function __construct(){
            //validate GD library
            $this->validateGD();
            $this->CI = &get_instance();
        }

        /**
        * 
        * Show error message
        * @param $str error string
        */        
        private function throwError($str){
            echo $str;
            exit();
        }
        
        public function set_jpeg_quality($quality)
        {
            $this->jpeg_quality = $quality;
        }

        /**
        * 
        * Set images folder
        * @param $folderImages
        */
        public function setImagesFolder($folderImages){
            //add '/' sign at the end
            if(!preg_match("/^.*\//", $folderImages)) $folderImages.="/";
            $this->dirImages = $folderImages;
        }

        /**
        * Validates that GD library exists. If not - print error
        */
        private function validateGD(){
            if(function_exists("gd_info") == false){
                echo "PHP GD library not found. Please enable it in php.ini";
                exit();
            }            
        }

        /**
        * 
        * get src image from filepath according the image type
        * @param string $filepath
        * @param string $type
        */
        private function getGdSrcImage($filepath,$type){
            // create the image
            $src_img = false;
            switch($type){
                case IMAGETYPE_JPEG:
                    $src_img = @imagecreatefromjpeg($filepath);
                    break;
                case IMAGETYPE_PNG:
                    $src_img = @imagecreatefrompng($filepath);
                    break;
                case IMAGETYPE_GIF:
                    $src_img = @imagecreatefromgif($filepath);
                    break;
                case IMAGETYPE_WBMP:
                    $src_img = @imagecreatefromwbmp($filepath);
                    break;
                default:
                    $this->throwError("wrong image format, can't resize");
                    break;
            }

            if($src_img == false) $this->throwError("Can't resize image: $filepath");
            return(array("success"=>true,"image"=>$src_img));
        }

        /**
        * 
        * save gd image to some filepath. return if success or not
        * @param img $dst_img
        * @param string $filepath
        * @param string $type
        */
        private function saveGdImage($dst_img,$filepath,$type){
            $successSaving = false;
            switch($type){
                case IMAGETYPE_JPEG:
                    $successSaving = imagejpeg($dst_img,$filepath,$this->jpeg_quality);
                    break;
                case IMAGETYPE_PNG:
                    $successSaving = imagepng($dst_img,$filepath);
                    break;
                case IMAGETYPE_GIF:
                    $successSaving = imagegif($dst_img,$filepath);
                    break;
                case IMAGETYPE_WBMP:
                    $successSaving = imagewbmp($dst_img,$filepath);
                    break;
            }

            return($successSaving);
        }

        /**
        * 
        * if the images are png or gif - handle image transparency
        * @param img $dst_img
        * @param string $imgType
        * @param number $newWidth
        * @param number $newHeight
        */
        private function handleTransparency(&$dst_img,$imgType,$newWidth,$newHeight){
            //handle transparency:
            if($imgType == IMAGETYPE_PNG || $imgType == IMAGETYPE_GIF){
                imagealphablending($dst_img, false);
                imagesavealpha($dst_img,true);
                $transparent = imagecolorallocatealpha($dst_img, 255,  255, 255, 127);
                imagefilledrectangle($dst_img, 0,  0, $newWidth, $newHeight,  $transparent);
            }
        }

        /**
        * 
        * crop image to specifix height and width , and save it to new path
        * @param string $imgSrc
        * @param number $thumbnail_width
        * @param number $thumbnail_height
        */
        private function create_thumbnail($imgSrc,$thumbnail_width,$thumbnail_height) { //$imgSrc is a FILE - Returns an image resource.
            //getting the image dimensions and type
            list($width_orig, $height_orig, $imgType) = getimagesize($imgSrc);

            $response = $this->getGdSrcImage($imgSrc,$imgType);
            if($response["success"] == false) return($response);

            $myImage = $response["image"];
            $ratio_orig = $width_orig/$height_orig;

            if ($thumbnail_width/$thumbnail_height > $ratio_orig) {
                $new_height = $thumbnail_width/$ratio_orig;
                $new_width = $thumbnail_width;
            } else {
                $new_width = $thumbnail_height*$ratio_orig;
                $new_height = $thumbnail_height;
            }

            $x_mid = $new_width/2;  //horizontal middle
            $y_mid = $new_height/2; //vertical middle

            $process = imagecreatetruecolor(round($new_width), round($new_height));
            
            $this->handleTransparency($process,$imgType,$new_width,$new_width);

            imagecopyresampled($process, $myImage, 0, 0, 0, 0, $new_width, $new_height, $width_orig, $height_orig);
            $thumb = imagecreatetruecolor($thumbnail_width, $thumbnail_height);
            
            $this->handleTransparency($thumb,$imgType,$thumbnail_width,$thumbnail_height);
            
            imagecopyresampled($thumb, $process, 0, 0, ($x_mid-($thumbnail_width/2)), ($y_mid-($thumbnail_height/2)), $thumbnail_width, $thumbnail_height, $thumbnail_width, $thumbnail_height);

            imagedestroy($process);
            imagedestroy($myImage);
            return $thumb;
        }


        public function thumbnail($filename,$maxWidth=-1,$maxHeight=-1,$filesave)
        {
            $filepath = $this->dirImages.$filename;
            $thumbnail = $this->create_thumbnail($filepath,$maxWidth,$maxHeight,$filesave);
            
            //getting the image dimensions and type
            list($width_orig, $height_orig, $imgType) = getimagesize($filepath);
            $this->saveGdImage($thumbnail,$filesave,$imgType);
        }
    }

?>
